/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
/* Copyright (C) 2012 Zongyou Yao. All rights reserved.     */

#ifndef ARENA_INCLUDED
#define ARENA_INCLUDED

#include "except.h"

/**
 * It is a checked runtime error to pass nbytes <= 0 or a null arena_t to
 * any arena function.
 */
typedef struct arena_t * arena_t;

extern const except_t arena_newfailed;
extern const except_t arena_failed;

/**
 * Allocates, initializes, and returns a new arena.
 */
arena_t arena_new(void);

/**
 * Deallocates all of the space in *ap, deallocates the arena itself, and
 * clears *ap. It is a checked runtime error for ap or *ap to be null.
 */
void arena_dispose(arena_t *ap);

/**
 * Allocates nbytes bytes in arena and returns a pointer to the first bytes.
 * The bytes are uninitialized. If arena_alloc raises arena_failed, file and line
 * are reported as the offending source coordinates.
 * Exception arena_failed can be raised.
 */
void * arena_alloc(arena_t arena, long nbytes, const char *file, int line);

/**
 * Allocates space in arena for an array of count elements, each occupying nbytes,
 * and returns a pointer to the first element. It is a checked runtime error for
 * count <= 0. The elements are uninitialized. If arena_calloc raises arena_failed,
 * file and line are reported as the offending source coordinates.
 * Exception arena_failed can be raised.
 */
void * arena_calloc(arena_t arena, long count, long nbytes, const char *file, int line);

/**
 * Deallocates all of the space in arena -- all of the space allocated since
 * the last call to arena_free.
 */
void arena_free(arena_t arena);

#endif
